﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace craigsPack
{
    /// <summary>
    /// Represents a Month and Day
    /// </summary>
    public struct WeakDate
    {
        private readonly int month;
        private readonly int day;

        private static readonly Dictionary<int,string[]> ValidMonths = new Dictionary<int,string[]>()
        {
            {1,new string[] { "jan","janurary","01"}},{2,new string[] { "feb","feburary","02"}},
            {3,new string[] { "mar","march","03"}},{4,new string[] { "apr","april","04"}},
            {5,new string[] { "may","05"}},{6,new string[] { "jun","june","06"}},
            {7,new string[] { "jul","july","07"}},{8,new string[] { "aug","august","08"}},
            {9,new string[] { "sep","sept","september","09"}},{10,new string[] { "oct","october"}},
            {11,new string[] {"nov","november"}},{12,new string[] { "dec","december"}},

        };
        private static readonly Dictionary<int, string[]> ValidDays = new Dictionary<int, string[]>()
        {
            
            {1,new string[] { "first","one"}},{2,new string[] { "second","two" }},
            {3,new string[] { "third","three"}},{4,new string[] {"fourth","four"}},
            {5,new string[] {"fith","five"}},{6,new string[] { "sixth","six"}},
            {7,new string[] { "seven","seventh"}},{8,new string[] { "eight","eight"}},
            {9,new string[] { "nine","ninth"}},{10,new string[] { "ten","tenth"}},
            {11,new string[] { "eleven", "eleventh"}},{12,new string[] { "tweleve","twelfth"}},
            {13,new string[] { "thirteen","thireenth"}},{14,new string[] { "fourteen","fourteenth"}},
            {15,new string[] { "fifteen", "fifteenth"}},{16,new string[] { "sixteen","sixeenth"}},
            {17,new string[] { "seventeen","seventeenth"}},{18,new string[] { "eighteen","eighteenth"}},
            {19,new string[] { "nineteen","nineteenth"}},{20,new string[] { "twenty","twentieth"}},
            {21,new string[] { "twentyfirst"}},{22,new string[] { "twentysecond","twentysecondth",}},
            {23,new string[] { "twentythird"}},{24,new string[] { "twentyfourth"}},
            {25,new string[] { "twentyfith"}},{26,new string[] { "twentysixth"}},
            {27,new string[] { "twentyseventh"}},{28,new string[] { "twentyeight"}},
            {29,new string[] { "twentynineth"}},{30,new string[] { "thirty","thirtyifth"}},
            {31,new string[] { "thirtyfirst"}}
        };
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="month">any value to represent a month ex(first,1,janurary)</param>
        /// <param name="day">any value to represent a day ex(second,2)</param>
        public WeakDate(string month,string day)
            :this()
        {
                month = month.ToLower();
                day = day.ToLower();
                try
                {
                    this.month = int.Parse(month);
                    this.day = int.Parse(day);

                    if (this.month <= 0 || this.day <= 0)
                    {
                        this.day = 0;
                        this.month = 0;

                        throw new ArgumentOutOfRangeException("Day and month have to be greater than 0");
                    }
                }
                catch
                {
                }
                try
                {
                    if (this.month == 0)
                        this.month = ValidMonths.First(o => o.Value.Any(o2 => o2 == month)).Key;
                    if (this.day == 0)
                        this.day = ValidDays.First(o => o.Value.Any(o2 => o2 == day) || o.Key.ToString() == day).Key;
                }
                catch
                {
                    if (this.month <= 0 || this.day <= 0)
                    {
                        this.day = 0;
                        this.month = 0;

                        throw new ArgumentOutOfRangeException("month/day","Day and month have to be greater than 0");
                    }
                }
        }
        public WeakDate(int month, int day)
            : this()
        {
            if (month <= 0 || day <= 0)
                throw new ArgumentOutOfRangeException("month/day","Day and month have to be greater than 0");

            this.month = month;
            this.day = day;
        }
        /// <summary>
        /// Gets a months numeric value
        /// </summary>
        public int Month
        {
            get { return month; }
        }
        /// <summary>
        /// Gets a day numeric value
        /// </summary>
        public int Day
        {
            get { return day; }
        }
    }
}
